home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 March: Reference Library / Dev.CD Mar 96 RL / Dev.CD Mar 96 RL.toast / Technical Documentation / develop / develop Issue 24 / develop Issue 24 code / Scriptable Database 1.0a11.sea / Scriptable Database 1.0a11 / Base / AbstractData.cp / AbstractData.cp
Encoding:
Text File  |  1995-10-10  |  6.5 KB  |  185 lines  |  [TEXT/MMCC]

  1.  
  2. #include "AbstractData.h"
  3.  
  4. //
  5. // For memcpy
  6. //
  7. #include <string.h>
  8.  
  9. //
  10. // Global list of compare behaviors
  11. //
  12. TAbstractCompareBehavior* TConstDataReference::fFirstBehavior = nil;
  13.  
  14. //--------------------------------------------------------------------------------
  15. // TAbstractCompareBehavior::TAbstractCompareBehavior
  16. //--------------------------------------------------------------------------------
  17. TAbstractCompareBehavior::TAbstractCompareBehavior()
  18.     {
  19.     fNextBehavior = nil;
  20.     }
  21.     
  22. //--------------------------------------------------------------------------------
  23. // TAbstractCompareBehavior::CompareDynamicBehavior
  24. //
  25. // Compare behaviors should look for data types they can compare
  26. //--------------------------------------------------------------------------------
  27. CompareEnumeration TAbstractCompareBehavior::CompareDynamicBehavior(const TConstDataReference& object1, const TConstDataReference& object2) const
  28. {
  29.     if(fNextBehavior)
  30.         return fNextBehavior->CompareDynamicBehavior(object1, object2);
  31.     else
  32.         return TConstDataReference::CompareDefaultBehavior(object1, object2);
  33. }
  34.  
  35. //--------------------------------------------------------------------------------
  36. // TAbstractCompareBehavior::ContainsDynamicBehavior
  37. //--------------------------------------------------------------------------------
  38. Boolean TAbstractCompareBehavior::ContainsDynamicBehavior(const TConstDataReference& object1, const TConstDataReference& object2) const
  39. {
  40.     if(fNextBehavior)
  41.         return fNextBehavior->ContainsDynamicBehavior(object1, object2);
  42.     else
  43.         return TConstDataReference::ContainsDefaultBehavior(object1, object2);
  44. }
  45.  
  46.  
  47. //--------------------------------------------------------------------------------
  48. // TConstDataReference::CopyTo
  49. //--------------------------------------------------------------------------------
  50. long TConstDataReference::CopyTo(char* destination, long maxBytesToCopy) const
  51. {
  52.     long bytesToCopy = (fDataLength > maxBytesToCopy) ? maxBytesToCopy : fDataLength;
  53.     
  54.     memcpy(destination, fData, bytesToCopy);
  55.     
  56.     return bytesToCopy;
  57. } // TConstDataReference::CopyTo
  58.  
  59. //--------------------------------------------------------------------------------
  60. // TConstDataReference::AddCompareBehavoir
  61. //--------------------------------------------------------------------------------
  62. void TConstDataReference::AddCompareBehavoir(TAbstractCompareBehavior* behavior)
  63.     {
  64.     if(fFirstBehavior != nil)
  65.         behavior->SetNextBehavior(fFirstBehavior);
  66.     
  67.     fFirstBehavior = behavior;
  68.     } // TConstDataReference::AddCompareBehavoir
  69.  
  70. //--------------------------------------------------------------------------------
  71. // TConstDataReference::Compare
  72. //--------------------------------------------------------------------------------
  73. CompareEnumeration TConstDataReference::Compare(const TConstDataReference& object1, const TConstDataReference& object2)
  74. {
  75.     if(fFirstBehavior)
  76.         return fFirstBehavior->CompareDynamicBehavior(object1, object2);
  77.     else
  78.         return TConstDataReference::CompareDefaultBehavior(object1, object2);
  79. }
  80.  
  81. //--------------------------------------------------------------------------------
  82. // TConstDataReference::Compare
  83. //--------------------------------------------------------------------------------
  84. CompareEnumeration TConstDataReference::Compare(const TConstDataReference& object2) const
  85. {
  86.     return TConstDataReference::Compare(*this, object2);
  87. }
  88.  
  89. //--------------------------------------------------------------------------------
  90. // TConstDataReference::CompareDefaultBehavior
  91. //
  92. // If none of the compare behaviors know how to do the data comparison, then
  93. // assume a simple byte-stream compare is good enough (works for C Strings)
  94. //--------------------------------------------------------------------------------
  95. CompareEnumeration TConstDataReference::CompareDefaultBehavior(const TConstDataReference& object1, const TConstDataReference& object2)
  96. {
  97.     const char* object1Data = object1.Data();
  98.     const char* object2Data = object2.Data();
  99.     long object1Length = object1.DataLength();
  100.     long object2Length = object2.DataLength();
  101.     long bytesToCompare = object1Length > object2Length ? object2Length : object1Length;
  102.     
  103.     //
  104.     // Scan through the first N bytes; stop comparing
  105.     // as soon as an unequal section is found
  106.     //
  107.     while(bytesToCompare)
  108.     {
  109.         if(*object2Data < *object1Data)
  110.             return kSecondObjectComesBefore;
  111.         if(*object2Data > *object1Data)
  112.             return kSecondObjectComesAfter;
  113.         
  114.         ++object1Data;
  115.         ++object2Data;
  116.         --bytesToCompare;
  117.     }
  118.     
  119.     //
  120.     // If the first N bytes of both data streams are
  121.     // the same, then the shorter structure comes before.
  122.     //
  123.     if(object2Length < object1Length)
  124.         return kSecondObjectComesBefore;
  125.     if(object2Length > object1Length)
  126.         return kSecondObjectComesAfter;
  127.     
  128.     //
  129.     // Every byte is equal & the length is the same,
  130.     // so the two objects are equal
  131.     //
  132.     return kObjectKeysEqual;
  133. }
  134.  
  135. //--------------------------------------------------------------------------------
  136. // TConstDataReference::Contains
  137. //--------------------------------------------------------------------------------
  138. Boolean TConstDataReference::Contains(const TConstDataReference& object2) const
  139. {
  140.     if(fFirstBehavior)
  141.         return fFirstBehavior->ContainsDynamicBehavior(*this, object2);
  142.     else
  143.         return TConstDataReference::ContainsDefaultBehavior(*this, object2);
  144. }
  145.  
  146. //--------------------------------------------------------------------------------
  147. // TConstDataReference::ContainsDefaultBehavior
  148. //--------------------------------------------------------------------------------
  149. Boolean TConstDataReference::ContainsDefaultBehavior(const TConstDataReference& object1, const TConstDataReference& object2)
  150. {
  151.     long sizeDifference = object1.DataLength() - object2.DataLength();
  152.     const char* dataStart = object1.Data();
  153.     Boolean isContained = false;
  154.     
  155.     while(sizeDifference >= 0)
  156.     {
  157.         TConstDataReference containsTest(object1.DataType(), dataStart, object2.DataLength());
  158.         if(containsTest.Compare(object2) == kObjectKeysEqual)
  159.         {
  160.             isContained = true;
  161.             break;
  162.         }
  163.         ++dataStart;
  164.         --sizeDifference;
  165.     }
  166.     
  167.     return isContained; 
  168. } // TConstDataReference::ContainsDefaultBehavior
  169.  
  170. //--------------------------------------------------------------------------------
  171. // TUpdataDataReference::CopyFrom
  172. //--------------------------------------------------------------------------------
  173. Boolean TUpdataDataReference::CopyFrom(const TConstDataReference& source, Boolean allowDataToClip)
  174. {
  175.     Boolean copyFits = source.DataLength() <= fMaxLength;
  176.     
  177.     if(copyFits || allowDataToClip)
  178.     {
  179.         fDataLength = source.CopyTo(fData, fMaxLength);
  180.         fDataType = source.DataType();
  181.     }
  182.     
  183.     return copyFits;
  184. } // TUpdataDataReference::CopyFrom
  185.